﻿using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;

namespace SopCastRecorder
{
	public static class Win32Api
	{
		private delegate int EnumWindowsDelegate(IntPtr hWnd, int lParam);
		[DllImport("user32.dll")]
		private static extern int EnumWindows(EnumWindowsDelegate lpEnumFunc, int lParam);

		[DllImport("user32.dll")]
		public static extern int IsWindowVisible(IntPtr hWnd);

		[DllImport("user32.dll", CharSet = CharSet.Auto)]
		private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
		public static string GetWindowTextCS(IntPtr hWnd)
		{
			var lpString = new StringBuilder(0xFF);
			GetWindowText(hWnd, lpString, 0xFF);
			return lpString.ToString();
		}

		[DllImport("User32.dll", EntryPoint = "SendMessage")]
		private static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, StringBuilder lParam);
		private const int WM_SETTEXT = 0x000C;
		private const int WM_CLOSE = 0x0010;
		private const int BM_CLICK = 0x00F5;

		[DllImport("User32.dll", EntryPoint = "PostMessage")]
		private static extern int PostMessage(IntPtr hWnd, int Msg, int wParam, StringBuilder lParam);
		private const int WM_KEYDOWN = 0x0100;
		private const int WM_KEYUP = 0x0101;
		private const int VK_RETURN = 0x000D;
		private const int WM_CHAR = 0x0102;
		public static void SetText(IntPtr hWnd, string str)
		{
			var lParam = new StringBuilder(str.Length);
			lParam.Append(str);
			SendMessage(hWnd, WM_SETTEXT, 0, lParam);
		}
		public static void SetText2(IntPtr hWnd, string str)
		{
			foreach (var c in str)
			{
				SendMessage(hWnd, WM_CHAR, c, null);
			}
		}
		public static void Close(IntPtr hWnd)
		{
			SendMessage(hWnd, WM_CLOSE, 0, null);
		}
		public static void Click(IntPtr hWnd)
		{
			SendMessage(hWnd, BM_CLICK, 0, null);
		}
		public static void Return(IntPtr hWnd)
		{
			PostMessage(hWnd, WM_KEYDOWN, VK_RETURN, null);
			PostMessage(hWnd, WM_KEYUP, VK_RETURN, null);
		}

		public delegate int D_EnumChildWindowsProc(IntPtr hWnd, int lParam);
		[DllImport("user32.dll")]
		public static extern int EnumChildWindows(IntPtr hwndParent, D_EnumChildWindowsProc lpEnumFunc, int lParam);

		[DllImport("user32.dll")]
		public static extern int GetClassNameA(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);

		[StructLayout(LayoutKind.Sequential, Pack = 4)]
		public struct RECT
		{
			public int left;
			public int top;
			public int right;
			public int bottom;
		}

		[DllImport("User32.Dll")]
		private static extern int GetWindowRect(IntPtr hWnd, out RECT rect);
		public static RECT GetWindowRectCS(IntPtr hWnd)
		{
			RECT rect;
			GetWindowRect(hWnd, out rect);
			return rect;
		}

		public static IntPtr[] GetHandles()
		{
			var handles = new List<IntPtr>();
			EnumWindows((hWnd, lParam) =>
			{
				if (IsWindowVisible(hWnd) == 0)
				{
					return 1;
				}
				handles.Add(hWnd);
				return 1;
			}, 0);
			return handles.ToArray();
		}

		public static void GetControls(IntPtr hWnd,Action<IntPtr[],IntPtr[]> callback)
		{
			var edits = new List<IntPtr>();
			var buttons = new List<IntPtr>();
			EnumChildWindows(hWnd, (childHWnd, lParam) =>
			{
				var lpClassName = new StringBuilder(0xFF);
				GetClassNameA(childHWnd, lpClassName, 0xFF);
				if (lpClassName.ToString() == "Edit")
				{
					edits.Add(childHWnd);
				}
				if (lpClassName.ToString() == "Button")
				{
					buttons.Add(childHWnd);
				}
				return 1;
			}, 0);

			callback(edits.ToArray(), buttons.ToArray());
		}
	}
}
